package com.iuie.ns.frame.utils;

import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.iuie.ns.frame.exception.ServiceException;

/**
 * List集合工具类
 * @author lj
 * @date 2017年6月5日 上午11:38:05
 */
public class ListUtils {
	
	private static final Logger logger = LoggerFactory.getLogger(ListUtils.class);
	
	private ListUtils(){
		
	}
	
	/**
	 * 判断list是否为空
	 * @param list
	 * @return
	 * @author lj
	 * @date 2017年6月5日 上午11:39:47
	 */
	public static boolean isEmpty(List<?> list) {
		return list == null || list.size() <= 0;
	}
	/**
	 * 判断list是否不为空
	 * @param list
	 * @return
	 * @author lj
	 * @date 2017年6月5日 上午11:39:37
	 */
	public static boolean isNotEmpty(List<?> list) {
		return !isEmpty(list);
	}
	
	/**
	 * 将List转成HashSet
	 * @param list
	 * @return
	 * @date 2017年6月11日 下午4:07:05
	 */
	public static <T> Set<T> toHashSet(List<T> list){
	    return new HashSet<>(list);
	}
	
	/**
	 * 将数组转为List
	 * @param objects
	 * @return
	 * @author iuie
	 * @date 2017年9月4日 下午5:57:40
	 */
	public static <T> List<T> arrayToList(T[] objects) {
		if (objects == null) {
			return null;
		}
		return Arrays.asList(objects);
	}
	
	/**
	 * 映射对象到List集合
	 * @param list
	 * @param attribute
	 * @return
	 */
	@SuppressWarnings("unchecked")
	public static <T, P> List<T> mapAttribute(List<P> list, String attribute) {
		if (StringUtils.isBlank(attribute)) {
			return null;
		}
		if (list == null || list.size() <= 0) {
			return null;
		}
		Class<P> clazz = (Class<P>) list.get(0).getClass();
		List<T> attrList = new ArrayList<>();
		try {
			for (P p : list) {
				Field field = ReflectionUtils.findField(clazz, attribute);
				field.setAccessible(true);
				Object obj = field.get(p);
				
				if (obj == null) {
					attrList.add(null);
				} else {
					T value = (T) obj;
					attrList.add(value);
				}
			}
		} catch (Exception e) {
			e.printStackTrace();
			logger.error("ListUtils.mapAttribute 方法执行错误， {}", e.getClass().getName());
			throw new ServiceException("系统错误，请联系管理员负责处理，（ListUtils.mapAttribute 方法执行错误，" + e.getClass().getName() + "）");
		}
		return attrList;
	}

	/**
	 * 判断集合中是否有元素的attribute的值和obj的attribute的值相等
	 * @param list
	 * @param obj
	 * @param attribute
	 * @return
	 */
	public static <T> boolean matchAttribute(List<T> list, T obj, String attribute) {
		if (list == null || list.size() <= 0 || obj == null) {
			return false;
		}
		try {
			// obj['attribute']
			Class<?> clazz = obj.getClass();
			Field field = clazz.getDeclaredField(attribute);
			field.setAccessible(true);
			Object objAttrVal = field.get(obj);
			
			// obj['attribute'] is null , return false
			if (objAttrVal == null) {
				return false;
			}
			
			boolean match = false;
			Iterator<T> it = list.iterator();
			while (it.hasNext()) {
				T o = it.next();
				Object oAttrVal = field.get(o);
				if (oAttrVal == null) {
					continue;
				}
				if (oAttrVal.equals(objAttrVal)) {
					match = true;
					break;
				}
			}
			return match;
		} catch (Exception e) {
			e.printStackTrace();
			throw new ServiceException("系统错误，请联系管理员负责处理，（ListUtils.matchAttribute 方法执行错误，" + e.getClass().getName() + "）");
		}
	}

	@SuppressWarnings("unchecked")
	public static <T, K, V> Map<K, V> toMap(List<T> list, String keyAttr, String valueAttr) {
		Map<K, V> map = new HashMap<K, V>();
		if (list == null || list.size() <= 0 || StringUtils.isBlank(keyAttr) || StringUtils.isBlank(valueAttr)) {
			return map;
		}
		try {
			
			for (T obj: list) {
				// obj['attribute']
				Class<?> clazz = obj.getClass();
				Field keyField = clazz.getDeclaredField(keyAttr);
				keyField.setAccessible(true);
				K keyObj = (K) keyField.get(obj);
				
				Field valueField = clazz.getDeclaredField(valueAttr);
				valueField.setAccessible(true);
				V valueObj = (V) valueField.get(obj);
				map.put(keyObj, valueObj);
			}
		} catch (Exception e) {
			e.printStackTrace();
			throw new ServiceException("系统错误，请联系管理员负责处理，（ListUtils.toMap 方法执行错误，" + e.getClass().getName() + "）");
		}
		return map;
	}
	
}
